<template>
    <div
      class="subtabs-pro"
      :class="[{ sticky }, size]"
      role="tablist"
      aria-label="设备信息子导航"
      ref="wrap"
      @keydown.left.prevent="focusPrev"
      @keydown.right.prevent="focusNext"
      @keydown.home.prevent="focusFirst"
      @keydown.end.prevent="focusLast"
    >
      <div class="scroll" ref="scroll">
        <button
          v-for="(it, i) in items"
          :key="it.key"
          class="tab"
          :class="{ active: it.key === modelValue, disabled: it.disabled }"
          role="tab"
          :aria-selected="it.key === modelValue"
          :tabindex="it.key === modelValue ? 0 : -1"
          @click="!it.disabled && update(it.key, i)"
          @focus="ensureVisible(i)"
        >
          <component v-if="it.icon" :is="it.icon" class="icon" />
          <span class="label">{{ it.label }}</span>
          <span v-if="it.badge != null" class="badge">{{ it.badge }}</span>
        </button>
  
        <!-- 动画指示条（ink） -->
        <div class="ink" :style="inkStyle"></div>
      </div>
      <!-- 两侧渐隐阴影，提示可横向滚动 -->
      <div class="fade left" />
      <div class="fade right" />
    </div>
  </template>
  
  <script setup>
  import { computed, onMounted, ref, watch, nextTick } from 'vue'
  
  const props = defineProps({
    modelValue: { type: String, required: true },
    items: { type: Array, default: () => [] }, // {key,label,icon?,badge?,disabled?}
    size: { type: String, default: 'md' },     // sm | md | lg
    sticky: { type: Boolean, default: false }   // 需要时吸顶
  })
  const emit = defineEmits(['update:modelValue'])
  
  const wrap = ref(null)
  const scroll = ref(null)
  const inkRect = ref({ left: 0, width: 0 })
  
  function update(key, i) {
    emit('update:modelValue', key)
    ensureVisible(i)
    placeInk()
  }
  
  function currentIndex() {
    return props.items.findIndex(i => i.key === props.modelValue)
  }
  function focusPrev() {
    const i = Math.max(0, currentIndex() - 1)
    if (props.items[i]) update(props.items[i].key, i)
  }
  function focusNext() {
    const i = Math.min(props.items.length - 1, currentIndex() + 1)
    if (props.items[i]) update(props.items[i].key, i)
  }
  function focusFirst() { props.items[0] && update(props.items[0].key, 0) }
  function focusLast()  { const i = props.items.length - 1; props.items[i] && update(props.items[i].key, i) }
  
  function ensureVisible(i) {
    const el = scroll.value?.children?.[i]
    if (!el || !scroll.value) return
    const r = el.getBoundingClientRect()
    const c = scroll.value.getBoundingClientRect()
    if (r.left < c.left) scroll.value.scrollBy({ left: r.left - c.left - 12, behavior: 'smooth' })
    if (r.right > c.right) scroll.value.scrollBy({ left: r.right - c.right + 12, behavior: 'smooth' })
  }
  
  function placeInk() {
    nextTick(() => {
      const i = currentIndex()
      const el = scroll.value?.children?.[i]
      if (!el) return
      const p = scroll.value.getBoundingClientRect()
      const r = el.getBoundingClientRect()
      inkRect.value = { left: r.left - p.left + scroll.value.scrollLeft, width: r.width }
    })
  }
  const inkStyle = computed(() => ({
    transform: `translateX(${inkRect.value.left}px)`,
    width: `${inkRect.value.width}px`
  }))
  
  onMounted(placeInk)
  watch(() => props.modelValue, placeInk)
  watch(() => props.items, placeInk, { deep: true })
  </script>
  
  <style scoped>
  :root{
    --st-bg: #f7f8fb;
    --st-border: #e5e7eb;
    --st-active-bg: #fff;
    --st-active-color: #111827;
    --st-color: #4b5563;
    --st-hover: #111827;
    --st-ink: #3b82f6;        /* 指示条颜色 */
  }
  
  /* 容器 */
  .subtabs-pro{
    position: relative;
    background: var(--st-bg);
    border: 1px solid var(--st-border);
    border-bottom: 0;                 /* 关键：不画底线，交由下面的面板绘制 */
    border-radius: 10px 10px 0 0;
    overflow: hidden;
  }
  .subtabs-pro.sticky{ position: sticky; top: 0; z-index: 10; }
  
  /* 滚动区 */
  .scroll{
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: none;            /* 火狐隐藏滚动条 */
    -ms-overflow-style: none;
    padding: 8px 12px 6px;
  }
  .scroll::-webkit-scrollbar{ display:none; }
  
  /* 渐隐阴影 */
  .fade{ position:absolute; top:0; bottom:0; width:16px; pointer-events:none; }
  .fade.left{ left:0; background: linear-gradient(90deg, #f7f8fb, rgba(247,248,251,0)); }
  .fade.right{ right:0; background: linear-gradient(270deg, #f7f8fb, rgba(247,248,251,0)); }
  
  /* Tab */
  .tab{
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid transparent;
    border-bottom: 0;                 /* 顶部卡片形态 */
    background: transparent;
    color: var(--st-color);
    border-radius: 8px 8px 0 0;
    padding: 10px 14px;
    font-size: 14px;
    white-space: nowrap;
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease, border-color .15s ease;
  }
  .tab:hover{ color: var(--st-hover); background: rgba(255,255,255,.6); }
  .tab.disabled{ opacity: .5; pointer-events: none; }
  
  .tab .icon{ width:16px; height:16px; }
  .badge{
    margin-left: 2px;
    padding: 0 6px;
    line-height: 18px;
    font-size: 12px;
    border-radius: 9px;
    background: #eef2ff;
    color: #4f46e5;
  }
  
  /* 选中态：白底、描边；下边不用边框，由面板接管 */
  .tab.active{
    color: var(--st-active-color);
    background: var(--st-active-bg);
    border-color: var(--st-border);
    z-index: 2;
  }
  
  /* 让选中项与下面面板无缝：用白色遮罩盖住面板顶边 */
  .tab.active::after{
    content:"";
    position:absolute;
    left: 0; right: 0;
    bottom: -1px;
    height: 2px;               /* 1px 线 + 1px 防锯齿余量 */
    background: var(--st-active-bg);
  }
  
  /* 动画指示条（在 tabs 容器内部底部） */
  .ink{
    position: absolute;
    left: 0; bottom: 0;
    height: 2px;
    background: var(--st-ink);
    border-radius: 2px;
    transition: transform .25s ease, width .25s ease;
  }
  
  /* 尺寸 */
  .subtabs-pro.sm .tab{ padding: 8px 12px; font-size: 13px; }
  .subtabs-pro.lg .tab{ padding: 12px 18px; font-size: 15px; }
  </style>
  